import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;

public class Config {

    /*@static variables*/

    public static Properties props;

    public static String message_text;
    public static String message_wav;
    public static String default_message;
    public static String sip_user;

    public static int sip_port;
    public static int http_port;

    public static InetAddress http_interface;
    public static InetAddress sip_interface;
        
    private static boolean current_message_specified = false;
    private static boolean current_message_exists = false;
    private static boolean default_message_specified = false;
    private static boolean default_message_exists = true;

    public Config(String[] args) throws Exception {

        SetDefaults();
        ReadConfigFile(args);

        //Command line has priority, so check it now for the rest of parameters
        int i;
        if (args.length>0)
        {
            for (i=0; i<args.length; i++)
            {
                if (args[i].equals("-user"))
                {
                    props.setProperty("sip_uri",args[i+1]);
                }
                if (args[i].equals("-http"))
                {
                    props.setProperty("http_bind_address",args[i+1]);
                }
            }
        }

        //At last, save parameters from Properties to fields of the Config class
        try
        {
            SaveParameters();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    private void SetDefaults() {
             
        try
        {
            http_interface = InetAddress.getLocalHost();
            sip_interface = http_interface;
            System.out.println("Default interface to listen: "+sip_interface.getHostAddress());
        }
        catch (UnknownHostException ex)
        {
            ex.printStackTrace();
        }        

        sip_user = "robot";
        sip_port = 5060;
        http_port = 80;
        message_text = "This is my very brilliant SIP speaker and it welcomes you here!"
                     + "I hope to get a good grade for this stuff as it was actually a lot of work!"
                     + "Well, this is the default message as you did not specify the one to use!";
        props = new Properties();
        props.setProperty("config_file","sipspeaker.cfg");
    }

    private void ReadConfigFile(String[] args) {

        //At first, we check if a config file is specified in command line

        int i;
        String filePath = null;

        if (args.length>0)
        {
            for (i=0; i<args.length; i++)
            {
                if (args[i].equals("-c"))
                {
                    props.setProperty("config_file",args[i+1]);
                    break;
                }
            }
        }

        //Now actually read everything
        try
        {
            //Check if it is a relative path (with no slash)
            if (props.getProperty("config_file").matches("^[0-9a-zA-Z\\.]+$"))
            {
                filePath = new File("").getAbsolutePath()+"/"+props.getProperty("config_file");
            }
            else
            {
                filePath = props.getProperty("config_file");
            }
            FileInputStream in = new FileInputStream(filePath);
            System.out.println("Using configuration file "+filePath);
            props.load(in);
        }
        catch (FileNotFoundException ex)
        {
            System.out.println("Config file not found: "+filePath+"; using default settings");
        }
        catch (IOException ex)
        {
            System.out.println("Error while reading from file: "+filePath+"; using default settings");
        }
    }

    private void SaveParameters() throws Exception {

        //Get the message text
        if (props.containsKey("message_text"))
        {
            message_text = props.getProperty("message_text");
        }

        //Check if a file to be played is specified
        if (props.containsKey("message_wav"))
        {
            current_message_specified = true;
            if (props.getProperty("message_wav").matches("^/.*"))
            {
                message_wav = props.getProperty(message_wav);
            }
            else
            {
                message_wav = new File("").getAbsolutePath()+"/"+props.getProperty("message_wav");
            }
        }

        //Check if such a file exists
        if (current_message_specified)
        {
            File cmf = new File(message_wav);
            System.out.println("Checking existence of the sound file");
            current_message_exists = (cmf.exists() ? true : false);
            System.out.println(current_message_exists);
        }

        //If it is not specified or non-existent
        if ((!current_message_specified) || (!current_message_exists))
        {
            System.out.println("Checking if a default file is specified");
            //Check if a default message is specified
            if (props.containsKey("default_message"))
            {
                default_message_specified = true;
                if (props.getProperty("default_message").matches("^/.*"))
                {
                    default_message = props.getProperty("default_message");
                }
                else
                {
                    default_message = new File("").getAbsolutePath()+"/"+props.getProperty("default_message");
                }
            }
            else
            {
                default_message_specified = false;
            }
            System.out.println(default_message_specified);

            //Check if such a file exists
            if (default_message_specified)
            {
                System.out.println("Checking existence of the default file");
                File dmf = new File(default_message);
                default_message_exists = (dmf.exists() ? true : false);
                System.out.println(default_message_exists);
            }

            //If a default message is also not specified or does not exist, create a new one
            if ((!default_message_specified) || (!default_message_exists))
            {
                System.out.println("Generating new default message");
                WavManager.GenerateDefaultMessage();
                default_message = "default.wav";
            }
        }

        if (props.containsKey("default_message"))
        {
            default_message = props.getProperty("default_message");
        }
        else
        {
            default_message = "default.wav";
        }
   
        if (props.containsKey("sip_interface"))
        {
            if (props.getProperty("sip_interface")!=null)
            {
                sip_interface = InetAddress.getByName(props.getProperty("sip_interface"));
            }
        }
        
        if (props.containsKey("sip_uri"))
        {
            String sip_uri = props.getProperty("sip_uri");
            sip_user = sip_uri.split("@")[0];
            if (sip_uri.matches("^.*:.*$"))
            {
               sip_port = Integer.parseInt(sip_uri.split(":")[1]);
               sip_interface = InetAddress.getByName(sip_uri.split("@")[1].split(":")[0]);
               System.out.println("Override by config file: SIP listens in interface "+sip_interface.getHostAddress());
            }
        }

        if (props.containsKey("http_port"))
        {
            http_port = Integer.parseInt(props.getProperty("http_port"));
        }

        if (props.containsKey("http_bind_address"))
        {
            String http_bind_address = props.getProperty("http_bind_address");
            if (http_bind_address.matches("^.*\\..*\\..*\\..*:.*$"))
            {
                http_interface = InetAddress.getByName(http_bind_address.split(":")[0]);
                http_port = Integer.parseInt(http_bind_address.split(":")[1]);
            }
            else
                if (http_bind_address.matches("^[0-9]+$"))
                {
                    http_port = Integer.parseInt(http_bind_address);
                }
         }
    }
        
}